package com.ict.web.task;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ict.common.utils.StringUtils;
import com.ict.common.utils.uuid.IdUtils;
import com.ict.system.mapper.SysUserRoleMapper;
import com.ict.web.constant.Constants;
import com.ict.web.constant.ProjectStatusEnum;
import com.ict.web.domain.AnnualProjectPlan;
import com.ict.web.domain.Approval;
import com.ict.web.domain.ExtractExpert;
import com.ict.web.domain.ProjectManagement;
import com.ict.web.mapper.AnnualProjectPlanMapper;
import com.ict.web.mapper.ProjectManagementMapper;
import com.ict.web.msg.domain.SysMsg;
import com.ict.web.msg.mapper.SysMsgMapper;
import com.ict.web.msg.util.CreateMsgUtil;
import com.ict.web.service.IAnnualProjectPlanService;
import com.ict.web.service.IApprovalService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * 异步工厂（产生任务用）
 */
public class RefreshStatusAsyncFactory {

    private static final Logger logger =
            LoggerFactory.getLogger(RefreshStatusAsyncFactory.class);

    /**
     * 同步年度计划状态
     *
     * @return 任务task
     */
    public static TimerTask asyncStatus(final IAnnualProjectPlanService annualProjectPlanService,
                                        final AnnualProjectPlanMapper annualProjectPlanMapper,
                                        final ProjectManagementMapper projectManagementMapper,
                                        final IApprovalService approvalService,
                                        final SysUserRoleMapper sysUserRoleMapper,
                                        final SysMsgMapper sysMsgMapper) {
        return new TimerTask() {
            @Override
            @Transactional(rollbackFor = Exception.class)
            public void run() {
                //定时刷新年度计划状态
                List<AnnualProjectPlan> list = annualProjectPlanMapper.selectList(
                            new QueryWrapper<AnnualProjectPlan>().notIn("is_state",ProjectStatusEnum.ANNUAL_PROJECT_PLAN_APPROVED));
                List<AnnualProjectPlan> planList = new ArrayList<>();

                List<Long> userIds = sysUserRoleMapper.getUserIdByRoleId(102L);

                if (CollectionUtil.isNotEmpty(list)) {
                    int size = list.size();
                    for (int i = 0; i < size; i++) {
                        AnnualProjectPlan projectPlan = list.get(i);
                        AnnualProjectPlan plan = new AnnualProjectPlan();
                        BeanUtils.copyProperties(projectPlan, plan);

                        if (LocalDateTime.now().isBefore(projectPlan.getStartTime())&&!projectPlan.getIsState().equals(Constants.ANNUAL_PROJECT_PLAN_NOT_STARTED)) {
                            //当前时间 在 开始时间 之前 状态变为 未启动
                            plan.setIsState(Constants.ANNUAL_PROJECT_PLAN_NOT_STARTED);
                            planList.add(plan);
                        } else if (LocalDateTime.now().isAfter(projectPlan.getStartTime())
                                && LocalDateTime.now().isBefore(projectPlan.getEndTime())
                                && !Constants.ANNUAL_PROJECT_PLAN_PAUSED.equals(projectPlan.getIsState())) {
                            //如果有多个到达申报时间的年度计划，只让第一个变更

                            long count = list.stream().limit(i + 1).filter(a ->
                                    StringUtils.equals(Constants.ANNUAL_PROJECT_PLAN_REPORTING, a.getIsState())).count();
                            //当前时间 在 开始时间 之后 截止时间 之前 并且状态非暂停 状态变为 正在申报
                            if (count < 1) {
                                plan.setIsState(Constants.ANNUAL_PROJECT_PLAN_REPORTING);
                                planList.add(plan);
                                for (Long userId:userIds){
                                    CreateMsgUtil.createMsgAnnualProjectPlan(CreateMsgUtil.ANNUAL_PLAN_TO_DO, userId, null,
                                            CreateMsgUtil.ANNUAL_PLAN_TO_DO, SysMsg.RESOURCE_TYPE_UNIT,null,plan.getPlanId());
                                }
                            }
                        } else if (LocalDateTime.now().isAfter(projectPlan.getEndTime())) {
                            //当前时间 在 截至时间 之后状态为正在申报 状态变为 待审核
                            if(projectPlan.getIsState().equals(Constants.ANNUAL_PROJECT_PLAN_REPORTING)){
                                plan.setIsState(Constants.ANNUAL_PROJECT_PLAN_TO_BE_REVIEWED);
                                planList.add(plan);
                            }
                            //修改消息可见
                            LambdaQueryWrapper<SysMsg> queryWrapper1 = new LambdaQueryWrapper<>();
                            queryWrapper1.eq(SysMsg::getPlanId,plan.getPlanId())
                                    .eq(SysMsg::getMsgStatus,"0");
                            List<SysMsg> sysMsgs = sysMsgMapper.selectList(queryWrapper1);
                            if (StringUtils.isNotNull(sysMsgs)) {
                                sysMsgs.forEach(s->{
                                    s.setMsgStatus("1");
                                    sysMsgMapper.updateById(s);
                                });
                            }

                            //年度计划下所有项目和对应的审核状态，变为待审核状态
                            QueryWrapper<ProjectManagement> wrapper = new QueryWrapper<>();
                            wrapper.eq("plan_id", projectPlan.getPlanId());
                            wrapper.eq("is_delete", ExtractExpert.DELETE_STATUS_NORMAL);
                            wrapper.notIn("is_state", Constants.STATEMENT_NOT_SUBMITTED);
                            wrapper.eq("is_state", Constants.DECLARATION_SUBMISSION_SUBMITTED);
                            List<ProjectManagement> managementList = projectManagementMapper.selectList(wrapper);
                            if (StringUtils.isNotEmpty(managementList)) {
                                managementList.stream().forEach(s -> {
                                    s.setIsState(Constants.APPLICATION_REVIEW_TO_BE_REVIEWED);
                                    s.setNode(ProjectStatusEnum.APPLICATION_REVIEW_TO_BE_REVIEWED.get().getNode());
                                    Approval approval = approvalService.plan(s.getProId());
                                    if (StringUtils.isNotNull(approval)) {
                                        approvalService.save(new Approval(IdUtils.snowId(), s.getProId(),
                                                ProjectStatusEnum.APPLICATION_REVIEW_TO_BE_REVIEWED.get().getStage(),
                                                ProjectStatusEnum.APPLICATION_REVIEW_TO_BE_REVIEWED.get().getNode(),
                                                LocalDateTime.now(), null, null,
                                                ProjectStatusEnum.APPLICATION_REVIEW_TO_BE_REVIEWED.get().getStatus(),
                                                "/", null, null, null, LocalDateTime.now(),
                                                Approval.APPROVAL_TYPE_PROJECT_MANAGE));
                                    }
                                    projectManagementMapper.updateById(s);
                                });
                            }
                        }
                        //待审核年度计划
                        if(projectPlan.getIsState().equals(Constants.ANNUAL_PROJECT_PLAN_TO_BE_REVIEWED)){
                            LambdaQueryWrapper<ProjectManagement> queryWrapper = new LambdaQueryWrapper<>();
                            queryWrapper.eq(ProjectManagement::getPlanId, plan.getPlanId());
                            queryWrapper.eq(ProjectManagement::getIsDelete, Constants.DELETE_STATUS_NORMAL);
                            List<ProjectManagement> projectManagementList =
                                    projectManagementMapper.selectList(queryWrapper);
                            List<ProjectManagement> collect1 = projectManagementList.stream()
                                    .filter(projectManagement -> Integer.parseInt(projectManagement.getIsState()) >= 2 && Integer.parseInt(projectManagement.getIsState()) !=53)
                                    .collect(Collectors.toList());
                            if(collect1.size() == projectManagementList.size() && projectManagementList.size() != 0 ){
                                //年度计划的所有项目全部审核完毕 状态变为 已审核
                                plan.setIsState(Constants.ANNUAL_PROJECT_PLAN_APPROVED);
                                planList.add(plan);
                            }
                        }
                    }
                    //是否有已启动/正在申报的
                    AtomicBoolean hasRunning = new AtomicBoolean(false);
                    planList = planList.stream().map(a -> {
                        if (StringUtils.equals(Constants.ANNUAL_PROJECT_PLAN_REPORTING, a.getIsState())) {
                            if (!hasRunning.get()) {
                                hasRunning.set(true);
                            } else if (hasRunning.get()) {
                                a.setIsState(Constants.ANNUAL_PROJECT_PLAN_NOT_STARTED);
                                //修改消息可见
                                LambdaQueryWrapper<SysMsg> queryWrapper1 = new LambdaQueryWrapper<>();
                                queryWrapper1.eq(SysMsg::getPlanId,a.getPlanId())
                                        .eq(SysMsg::getMsgStatus,"0");
                                List<SysMsg> sysMsgs = sysMsgMapper.selectList(queryWrapper1);
                                if (StringUtils.isNotNull(sysMsgs)) {
                                    sysMsgs.forEach(s->{
                                        s.setMsgStatus("1");
                                        sysMsgMapper.updateById(s);
                                    });
                                }
                            }
                        }
                        return a;
                    }).collect(Collectors.toList());
                    if(StringUtils.isNotEmpty(planList)){
                        annualProjectPlanService.batchUpdate(planList);
                    }

                }
                logger.info("同步同步年度计划状态：");
            }
        };
    }
}
